######################################################
######################################################
#              XBMC Script for SageTV                #
#          by Brian Pattison aka Coolwave            #
#               coolwave6@yahoo.com                  #
#          updated by Mike Williams                  #
#               mike_at_cisco@yahoo.com              #
#                                                    #
#   This is my first experience with Python.         #
#   Thanks to all the great scripts out there        #
#   for me to get code from. This script wouldn't    #
#   exist without nielm's webserver for SageTV.      #
#   The guys at Frey of course rock for creating     #
#   such an extensible piece of software in SageTV.  #
#   Same goes to the XMBC developers! Rock on!       #
#   Thanks also to the crazy graphic designers       #
#   creating all the skins for MediaPortal. Your     #
#   Graphics are used in every PVR program out there #
#   and we love them. Please switch to SageTV so we  #
#   can have you all creating new STVs. :)           #
#                                                    #
######################################################
######################################################

import os, threading, xbmc, xbmcgui, time, datetime
import urllib, urllib2, re, copy, xml.dom.minidom
import copy, SageLib, urllib
from string import split, replace, find
from xml.dom import Node

try: Emulating = xbmcgui.Emulating
except: Emulating = False
dialog = xbmcgui.Dialog()

if Emulating:
    dirHome = 'Q:\\scripts\\SageTV\\'
else:
    dirHome = str(os.getcwd()) + '\\'
    dirHome = dirHome.replace(";", "")

#Remove trailing ; if they exist
dirHome = dirHome.replace(';','')
SageLib.setDirhome(dirHome)

#Figure out time offset
offset = datetime.datetime.utcnow() - datetime.datetime.now()
SageLib.setOffset(offset)

#Declare global static variables
# Only set for remote.  Needs controller also
ACTION_MOVE_LEFT        = 1
ACTION_MOVE_RIGHT       = 2
ACTION_MOVE_UP          = 3
ACTION_MOVE_DOWN        = 4
ACTION_PAGE_UP          = 5
ACTION_PAGE_DOWN        = 6
ACTION_SELECT_ITEM      = 7
ACTION_HIGHLIGHT_ITEM   = 8
ACTION_BACK             = 9
ACTION_MENU             = 10
ACTION_INFO             = 11
ACTION_PAUSE            = 12
ACTION_STOP             = 13
ACTION_SKIP_FORWARD     = 14
ACTION_SKIP_BACK        = 15
ACTION_DISPLAY          = 18
ACTION_FASTFORWARD      = 77
ACTION_REWIND           = 78
ACTION_PLAY             = 79
ACTION_SCROLL_UP        = 111
ACTION_SCROLL_DOWN      = 112
ACTION_TITLE            = 117
SORTBYDATEDESC          = 0
SORTBYDATEASC           = 1
SORTBYTITLE             = 2

#Settings Window
class SettingsWindow(xbmcgui.Window):
    def __init__(self):
        self.Refresh()

    def drawBackground(self):
        #Background and Labels Draw
        global settings
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight,settings.imgBackground))
        self.addControl(SageLib.image(35,15,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(156,47,400,20)
        self.strActionInfo.setLabel('Settings')
        self.addControl(self.strActionInfo)

    def drawLeftButtons(self):
        #Draw Left Buttons
        global settings
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(5,95+36*i,165,30)
            self.addControl(button)
            button.setLabel(self.LeftButtonTitles[i])
            self.buttonLeft.append(button)

    def drawLabels(self):
        global settings
        # Draw Connection Info - Ipaddress, Port, UserId, Password
        self.ipaddress = SageLib.button(180,90,400,25)
        self.addControl(self.ipaddress)
        self.ipaddress.setLabel('IP Address: '+settings.ipaddress)
        self.port = SageLib.button(180,115,400,25)
        self.addControl(self.port)
        self.port.setLabel('Port: '+settings.port)
        self.userid = SageLib.button(180,140,400,25)
        self.addControl(self.userid)
        self.userid.setLabel('Login: '+settings.userid)
        self.password = SageLib.button(180,165,400,25)
        self.addControl(self.password)
        self.password.setLabel('Password: '+settings.password)
        # Draw Appearance Info - Skin, ShowEpisodeNames, ShowDontLike, ShowArchive, AutoRefresh
        self.skin = SageLib.button(180,190,400,25)
        self.addControl(self.skin)
        self.skin.setLabel('Skin: '+settings.dirSkin)
        self.showepisodenames = SageLib.button(180,215,400,25)
        self.addControl(self.showepisodenames)
        self.showepisodenames.setLabel('Show Episode Names: '+str(settings.ShowEpisodeNames))
        self.showdontlike = SageLib.button(180,240,400,25)
        self.addControl(self.showdontlike)
        self.showdontlike.setLabel("Show Don't Like: "+str(settings.ShowDontLike))
        self.showarchive = SageLib.button(180,265,400,25)
        self.addControl(self.showarchive)
        self.showarchive.setLabel('Show Archived: '+str(settings.ShowArchive))
        self.autorefresh = SageLib.button(180,290,400,25)
        self.addControl(self.autorefresh)
        self.autorefresh.setLabel('Auto Refresh: '+str(settings.AutoRefresh))
        # Draw Graphics Info - Resolution, xoffset, yoffset
        self.resolution = SageLib.button(180,315,400,25)
        self.addControl(self.resolution)
        self.resolution.setLabel('Resolution: '+self.Resolutions[settings.Resolution])
        self.xoffset = SageLib.button(180,340,400,25)
        self.addControl(self.xoffset)
        self.xoffset.setLabel('Horizontal Adjust: '+str(settings.x))
        self.yoffset = SageLib.button(180,365,400,25)
        self.addControl(self.yoffset)
        self.yoffset.setLabel("Vertical Adjust: "+str(settings.y))
        # Draw System Info - RecordingPath, XBMCPath
        self.recordingpath = SageLib.button(180,390,400,25)
        self.addControl(self.recordingpath)
        self.recordingpath.setLabel('Recordings Path: '+','.join(settings.RecordingPath))
        self.xbmcpath = SageLib.button(180,415,400,25)
        self.addControl(self.xbmcpath)
        self.xbmcpath.setLabel('XBMC Path: '+','.join(settings.XBMCPath))

    def flowControl(self):
        # Add controls
        self.ipaddress.setNavigation(self.xbmcpath, self.port, self.buttonLeft[0], self.buttonLeft[0])
        self.port.setNavigation(self.ipaddress, self.userid, self.buttonLeft[0], self.buttonLeft[0])
        self.userid.setNavigation(self.port, self.password, self.buttonLeft[0], self.buttonLeft[0])
        self.password.setNavigation(self.userid, self.skin, self.buttonLeft[0], self.buttonLeft[0])
        self.skin.setNavigation(self.password, self.showepisodenames, self.buttonLeft[0], self.buttonLeft[0])
        self.showepisodenames.setNavigation(self.skin, self.showdontlike, self.buttonLeft[0], self.buttonLeft[0])
        self.showdontlike.setNavigation(self.showepisodenames, self.showarchive, self.buttonLeft[0], self.buttonLeft[0])
        self.showarchive.setNavigation(self.showdontlike, self.autorefresh, self.buttonLeft[0], self.buttonLeft[0])
        self.autorefresh.setNavigation(self.showarchive, self.resolution, self.buttonLeft[0], self.buttonLeft[0])
        self.resolution.setNavigation(self.autorefresh, self.xoffset, self.buttonLeft[0], self.buttonLeft[0])
        self.xoffset.setNavigation(self.resolution, self.yoffset, self.buttonLeft[0], self.buttonLeft[0])
        self.yoffset.setNavigation(self.xoffset, self.recordingpath, self.buttonLeft[0], self.buttonLeft[0])
        self.recordingpath.setNavigation(self.yoffset, self.xbmcpath, self.buttonLeft[0], self.buttonLeft[0])
        self.xbmcpath.setNavigation(self.recordingpath, self.ipaddress, self.buttonLeft[0], self.buttonLeft[0])
        for i in range(len(self.buttonLeft)):
            self.buttonLeft[i].setNavigation(self.buttonLeft[i-1], self.buttonLeft[(i+1)%len(self.buttonLeft)], self.ipaddress, self.ipaddress)

    def fillList(self):
        self.Resolutions = []
        self.Resolutions.append('1080i')
        self.Resolutions.append('720p')
        self.Resolutions.append('480p')
        self.Resolutions.append('480p Widescreen')
        self.Resolutions.append('NTSC')
        self.Resolutions.append('NTSC Widescreen')
        self.Resolutions.append('PAL')
        self.Resolutions.append('PAL Widescreen')
        self.Resolutions.append('PAL60')
        self.Resolutions.append('PAL60 Widescreen')

    def onAction(self, value):
        action = value.getId()
        if action == ACTION_MENU or action == ACTION_BACK: self.close()

    def Refresh(self):
        #time.sleep(1)
        global settings
        settings.populate()
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.LeftButtonTitles = ['Back']
        self.drawBackground()
        self.drawLeftButtons()
        self.fillList()
        self.drawLabels()
        self.flowControl()
        self.setFocus(self.buttonLeft[0])


    def onControl(self, control):
        global settings
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "Back":
                    self.close()
        if control == self.ipaddress:
            value = dialog.numeric(3, "IP Address of Sage Server", settings.ipaddress)
            settings.update("Connection", "Ipaddress", value)
            self.Refresh()
        if control == self.port:
            value = dialog.numeric(0, "Sage Webserver Port", settings.port)
            settings.update("Connection", "Port", value)
            self.Refresh()
        if control == self.userid:
            keyboard = xbmc.Keyboard(settings.userid)
            keyboard.doModal()
            if (keyboard.isConfirmed()):
                value = keyboard.getText()
                settings.update("Connection", "UserId", value)
            self.Refresh()
        if control == self.password:
            keyboard = xbmc.Keyboard(settings.password)
            keyboard.doModal()
            if (keyboard.isConfirmed()):
                value = keyboard.getText()
                settings.update("Connection", "Password", value)
            self.Refresh()
        if control == self.skin:
            tempList = os.listdir(dirHome + "skins\\")
            value = dialog.select("Choose a skin", tempList)
            settings.update("Appearance", "Skin", tempList[value])
            self.Refresh()
        if control == self.showepisodenames:
            value = dialog.yesno("Display episode names?", "")
            if value: settings.update("Appearance", "ShowEpisodeNames", "True")
            else: settings.update("Appearance", "ShowEpisodeNames", "False")
            self.Refresh()
        if control == self.showdontlike:
            value = dialog.yesno("Display shows you have marked as not liking?", "")
            if value: settings.update("Appearance", "ShowDontLike", "True")
            else: settings.update("Appearance", "ShowDontLike", "False")
            self.Refresh()
        if control == self.showarchive:
            value = dialog.yesno("Display archived shows?", "")
            if value: settings.update("Appearance", "ShowArchived", "True")
            else: settings.update("Appearance", "ShowArchived", "False")
            self.Refresh()
        if control == self.autorefresh:
            value = dialog.yesno("Auto Refresh?", "warning will slow down operations")
            if value: settings.update("Appearance", "AutoRefresh", "True")
            else: settings.update("Appearance", "AutoRefresh", "False")
            self.Refresh()
        if control == self.resolution:
            value = dialog.select("Choose a resolutions", self.Resolutions)
            settings.update("Graphics", "Resolution", str(value))
            self.Refresh()
        if control == self.xoffset:
            value = dialog.numeric(0, "Horizontal Offset", str(settings.x))
            settings.update("Graphics", "xoffset", str(value))
            self.Refresh()
        if control == self.yoffset:
            value = dialog.numeric(0, "Vertical Offset", str(settings.y))
            settings.update("Graphics", "yoffset", str(value))
            self.Refresh()
        if control == self.recordingpath:
            dialog.ok("This entry is case sensitive", "Paths must end in \\ and have no spaces")
            tempPath = ",".join(settings.RecordingPath)
            keyboard = xbmc.Keyboard(tempPath)
            keyboard.doModal()
            if (keyboard.isConfirmed()):
                value = keyboard.getText()
                settings.update("System", "RecordingPath", value)
            self.Refresh()
        if control == self.xbmcpath:
            dialog.ok("This entry is case sensitive", "Paths must end in / and have no spaces")
            tempPath = ",".join(settings.XBMCPath)
            keyboard = xbmc.Keyboard(tempPath)
            keyboard.doModal()
            if (keyboard.isConfirmed()):
                value = keyboard.getText()
                settings.update("System", "XBMCPath", value)
            self.Refresh()
#End Settings Window

#Get Settings from file
settings = SageLib.Settings()
settings.populate()

#Get information from user if its not in the file
if settings.ipaddress == "0.0.0.0":
    popup = SettingsWindow()
    popup .doModal()
    del popup

#Get Current Date/Connect to webserver
webaddress = "http://" + settings.userid + ":" + settings.password + "@" + settings.ipaddress + ":" + settings.port
SageLib.setWebaddress(webaddress)

CURRENT_DATE_OBJ = datetime.datetime.now()
CURRENT_DATE     = CURRENT_DATE_OBJ.strftime("%m/%d/%Y")
SageLib.setCurrentDate(CURRENT_DATE)
SageLib.setSettings(settings)

try:
    WebHTML = SageLib.GetWebPage(webaddress + "/sage/Home")
    Connect = True
except:
    dialog.ok("Connection Error", webaddress + "/sage/Home")
    Connect = False

SearchVar       = ""
SearchVarString = ""
CurrentShow     = SageLib.Show()
FavoriteId      = 0
SearchRecorded  = []
LastSearch      = datetime.datetime(2007, 1, 1, 0, 0, 0) # A really old date so we know an update is needed

##
# STARTUP WINDOW
# This is the main screen and starting point.
##
class SageMain(xbmcgui.Window):
    def __init__(self):
        self.Refresh()

    def drawBackground(self):
        # Draw background. The resolution selected needs to have a background with it
        # so that the image is not all warped
        self.addControl(xbmcgui.ControlImage(0, 0, settings.screenWidth, settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70, settings.imgTVLogo))
        self.strActionInfo = SageLib.label(125,60,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('My TV')

    def getRecentRecordings(self):
        # Grab the last 10 recordings
        self.Results = SageLib.MFActions().getMediaFiles(10, "date", "true")

    def getUpcomingRecordings(self):
        # Get the next 5 programs to record
        self.UpcomingPrograms = SageLib.GlobalActions().getScheduledRecordings(5, "date", "false")

    def drawRecentRecordings(self):
        self.strActionInfo = SageLib.label(178,94,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Recent Recordings')

        self.lstRecentRecordings = SageLib.clist(178,120,450,170)
        self.addControl(self.lstRecentRecordings)
        self.imgRecentRecording = []
        self.imgRecentWatched   = []
        self.imgRecentArchived  = []
        for i in range(len(self.Results)):
            self.imgRecentRecording.append(SageLib.image(500,124+30*i,20,20,settings.imgRecording))
            self.addControl(self.imgRecentRecording[i])
            self.imgRecentWatched.append(SageLib.image(522,124+30*i,20,20,settings.imgWatched))
            self.addControl(self.imgRecentWatched[i])
            self.imgRecentArchived.append(SageLib.image(544,124+30*i,20,20,settings.imgArchived))
            self.addControl(self.imgRecentArchived[i])
            self.imgRecentWatched[i].setVisible(False)
            self.imgRecentArchived[i].setVisible(False)
            self.imgRecentRecording[i].setVisible(False)

    def fillRecentRecordings(self):
        self.lstRecentRecordings.reset()
        if not Emulating:
            for i in range(len(self.Results)):
                listitem = xbmcgui.ListItem()
                # Show the episode name if that is the preference and it exists
                if (self.Results[i].episode != "" and settings.ShowEpisodeNames):
                    listitem.setLabel(self.Results[i].title + ' - "' + self.Results[i].episode + '"')
                else:
                    listitem.setLabel(self.Results[i].title)
                # If its from today show the time, otherwise the date
                if self.Results[i].datestamp == CURRENT_DATE:
                    listitem.setLabel2(self.Results[i].timestamp)
                else:
                    listitem.setLabel2(self.Results[i].datestamp)
                self.lstRecentRecordings.addItem(listitem)

                # If any mediafile is archived we set the flag
                # If any airing is watched we set the flag
                for j in range(len(self.Results[i].airings)):
                    if SageLib.AiringActions().isWatched(self.Results[i].airings[j].sageDbId):
                        self.imgRecentWatched[i].setVisible(True)
                    for k in range(len(self.Results[i].airings[j].mediaFiles)):
                        if self.Results[i].airings[j].mediaFiles[k].archived:
                            self.imgRecentArchived[i].setVisible(True)
                if cmp(self.Results[i].startTime, CURRENT_DATE_OBJ) >= 0:
                    seconds = self.Results[i].startTime - CURRENT_DATE_OBJ
                    delta   = datetime.timedelta(seconds=int(self.Results[i].duration))
                    if seconds <= delta:
                        self.imgRecentRecording[i].setVisible(True)

    def drawUpcomingRecordings(self):
        self.strActionInfo = SageLib.label(178,286,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Upcoming Recordings')

        self.lstUpcomingRecordings = SageLib.clist(178,312,450,170)
        self.addControl(self.lstUpcomingRecordings)
        self.imgUpcomingRecording = []
        self.imgUpcomingWatched   = []
        for i in range(len(self.UpcomingPrograms)):
            self.imgUpcomingRecording.append(SageLib.image(500,314+30*i,20,20,settings.imgRecording))
            self.addControl(self.imgUpcomingRecording[i])
            self.imgUpcomingWatched.append(SageLib.image(522,314+30*i,20,20,settings.imgWatched))
            self.addControl(self.imgUpcomingWatched[i])
            self.imgUpcomingRecording[i].setVisible(False)
            self.imgUpcomingWatched[i].setVisible(False)

    def fillUpcomingRecordings(self):
        self.lstUpcomingRecordings.reset()
        if not Emulating:
            for i in range(len(self.UpcomingPrograms)):
                listitem = xbmcgui.ListItem()
                if (self.UpcomingPrograms[i].episode != "" and settings.ShowEpisodeNames):
                    listitem.setLabel(self.UpcomingPrograms[i].title + ' - "' + self.UpcomingPrograms[i].episode + '"')
                else:
                    listitem.setLabel(self.UpcomingPrograms[i].title)
                # If its from today show the time, otherwise the date
                if self.UpcomingPrograms[i].datestamp == CURRENT_DATE:
                    listitem.setLabel2(self.UpcomingPrograms[i].timestamp)
                else:
                    listitem.setLabel2(self.UpcomingPrograms[i].datestamp)
                self.lstUpcomingRecordings.addItem(listitem)

                # If any airing is watched we set the flag
                for j in range(len(self.UpcomingPrograms[i].airings)):
                    if SageLib.AiringActions().isWatched(self.UpcomingPrograms[i].airings[j].sageDbId):
                        self.imgUpcomingWatched[count].setVisible(True)
                if cmp(self.UpcomingPrograms[i].startTime, CURRENT_DATE_OBJ) >= 0:
                    seconds = self.UpcomingPrograms[i].startTime - CURRENT_DATE_OBJ
                    delta   = datetime.timedelta(seconds=int(self.UpcomingPrograms[i].duration))
                    if seconds <= delta:
                        self.imgUpcomingRecording[i].setVisible(True)

    def drawLeftButtons(self):
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(6,94+26*i,164,20)
            button.setLabel(self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)

        for i in range(len(self.LeftButtonTitles)):
            self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
            self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
            self.buttonLeft[i].controlRight(self.lstRecentRecordings)

    def Refresh(self):
        # Set the screen resolution NTSC, PAL, 1080i, etc
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.LeftButtonTitles = ['Recorded TV','Grid Guide','Guide','Movies','Intelligent Picks','Schedule','Search : Title','Search : Keyword','Conversion Queue','Settings']
        if not settings.AutoRefresh: self.LeftButtonTitles.append('Refresh')
        self.LeftButtonTitles.append('Quit')
        self.drawBackground()
        self.getRecentRecordings()
        self.getUpcomingRecordings()
        self.drawRecentRecordings()
        self.drawUpcomingRecordings()
        self.fillRecentRecordings()
        self.fillUpcomingRecordings()
        self.drawLeftButtons()
        self.setButtonControls()
        self.setFocus(self.buttonLeft[0])

    def setButtonControls(self):
        self.lstRecentRecordings.controlLeft(self.buttonLeft[0])
        self.lstRecentRecordings.controlRight(self.lstUpcomingRecordings)
        self.lstUpcomingRecordings.controlLeft(self.buttonLeft[0])

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK): self.close()
        elif (action == ACTION_PLAY):
            if self.getFocus() == self.lstRecentRecordings:
                selected = self.lstRecentRecordings.getSelectedPosition()
                #Watch
                playlist = xbmc.PlayList(1)
                playlist.clear()
                for i in range(len(self.Results[selected].airings)):
                    for j in range(len(self.Results[selected].airings[i].mediaFiles)):
                        for k in range(len(self.Results[selected].airings[i].mediaFiles[j].segments)):
                            seg = self.Results[selected].airings[i].mediaFiles[j].segments[k].filePath
                            #Convert to settings.XBMCPath if they are available
                            for l in range(len(settings.RecordingPath)):
                                tempPath = settings.RecordingPath[l]
                                seg = seg.replace(tempPath,settings.XBMCPath[l])
                                seg = seg.replace("\\", "/")
                                seg = xbmc.translatePath(seg)
                            # If its not a samba mount we can't get to it directly.  It sounds odd, but do not add the s or even if it finds it the value will be 0
                            if seg.find("mb://") == 0:
                                webfile = webaddress + '/sagepublic/PlaylistGenerator?Command=Generate&pltype=m3u&fntype=url&MediaFileId=' + str(CurrentShow.airings[i].mediaFiles[j].sageDbId)
                                localfile = dirHome + 'streamplaylist.m3u'
                                SageLib.stream.downloadURL(webfile,localfile)
                                seg = localfile
                            playlist.add(seg)
                p = xbmc.Player()
                p.play(playlist)
                while(p.isPlayingVideo()):
                    for i in range(len(self.Results[selected].airings)):
                        SageLib.AiringActions().SetWatched(self.Results[selected].airings[i].sageDbId)
                    time.sleep(1)
        elif (action == ACTION_INFO):
            if self.getFocus() == self.lstRecentRecordings:
                selected = self.lstRecentRecordings.getSelectedPosition()
                CurrentShow = copy.copy(self.lstRecentRecordings[selected])
                popup = SageProgramInfo()
                popup .doModal()
                del popup
                if settings.AutoRefresh:
                    self.Refresh()
                    try: self.lstRecentRecordings.selectItem(selected)
                    except: self.lstRecentRecordings.selectItem(0)
            elif self.getFocus() == self.lstUpcomingRecordings:
                selected = self.lstUpcomingRecordings.getSelectedPosition()
                CurrentShow = copy.copy(self.lstUpcomingRecordings[selected])
                popup = SageProgramInfo()
                popup .doModal()
                del popup
                if settings.AutoRefresh:
                    self.Refresh()
                    try: self.lstUpcomingRecordings.selectItem(selected)
                    except: self.lstUpcomingRecordings.selectItem(0)


    def onControl(self, control):
        global CurrentShow
        #One of the Recent Recordings was selected
        if control == self.lstRecentRecordings:
            selected = self.lstRecentRecordings.getSelectedPosition()
            CurrentShow = copy.copy(self.Results[selected])
            popup = SageProgramInfo()
            popup .doModal()
            del popup
            if settings.AutoRefresh:
                self.Refresh()
                try: self.lstRecentRecordings.selectItem(selected)
                except: self.lstRecentRecordings.selectItem(0)

        #One of the Upcoming Recordings was selected
        if control == self.lstUpcomingRecordings:
            selected = self.lstUpcomingRecordings.getSelectedPosition()
            CurrentShow = copy.copy(self.UpcomingPrograms[selected])
            popup = SageProgramInfo()
            popup .doModal()
            del popup
            if settings.AutoRefresh:
                self.Refresh()
                try: self.lstUpcomingRecordings.selectItem(selected)
                except: self.lstUpcomingRecordings.selectItem(0)

        #Left Buttons
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "Recorded TV":
                    #RecordedTV
                    self.displayResults("getRecordedTV", "")
                    if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Guide":
                    #Guide
                    popup = SageGuide()
                    popup .doModal()
                    del popup
                    if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Grid Guide":
                    #Guide
                    popup = SageGridGuide()
                    popup .doModal()
                    del popup
                    if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Movies":
                    #Movies
                    self.displayResults("getMovies", "")
                    if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Intelligent Picks":
                    #Intelligent Picks by SageTV
                    self.displayResults("getIntelligent", "")
                    if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Schedule":
                    #Schedule
                    self.displayResults("getSchedule", "")
                    if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Search : Title":
                    #Search : Title
                    keyboard = xbmc.Keyboard('')
                    keyboard.doModal()
                    if (keyboard.isConfirmed()):
                        self.displayResults("getSearchTitle", keyboard.getText())
                        if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Search : Keyword":
                    #Search : Keyword
                    keyboard = xbmc.Keyboard('')
                    keyboard.doModal()
                    if (keyboard.isConfirmed()):
                        self.displayResults("getSearchKeyword", keyboard.getText())
                        if settings.AutoRefresh: self.Refresh()

                if self.LeftButtonTitles[i] == "Conversion Queue":
                    #Conversion Queue
                    popup = SageConversion()
                    popup .doModal()
                    del popup

                if self.LeftButtonTitles[i] == "Settings":
                    #Conversion Queue
                    popup = SettingsWindow()
                    popup .doModal()
                    del popup
                    self.Refresh()

                if self.LeftButtonTitles[i] == "Refresh":
                    self.Refresh()

                if self.LeftButtonTitles[i] == "Quit":
                    self.close()

    def displayResults(self, searchvar, searchvarstring):
        global SearchVar
        global SearchVarString
        SearchVar       = searchvar
        SearchVarString = searchvarstring
        popup           = SageSearchResults()
        popup .doModal()
        del popup
#End Startup Window

#SEARCH RESULTS WINDOW
class SageSearchResults(xbmcgui.Window):
    def __init__(self):
        self.setCoordinateResolution(settings.Resolution)
        global SearchVar
        global SearchVarString
        if Emulating: xbmcgui.Window.__init__(self)
        self.SortBy           = "Date"
        self.isRefreshed      = False
        self.BasePrograms     = []
        self.LeftButtonTitles = []
        self.Filter           = "No Filter"
        if (SearchVar == "getRecordedTV" and SearchVarString == ""):
            self.LeftButtonTitles.append(self.Filter)
            self.SortBy = settings.grab("RecordedTV","SortBy")
        elif SearchVar == "getMovies":
            self.SortBy = settings.grab("Movies","SortBy")
        elif SearchVar == "getSchedule":
            self.SortBy = settings.grab("Schedule","SortBy")
        if self.SortBy.lower() == "title":
            self.LeftButtonTitles.append('Sort By Title')
        else:
            self.LeftButtonTitles.append('Sort By Date')
        if SearchVar == "getRecordedTV":
            if SearchVarString == "":
                self.LeftButtonTitles.append('Schedule')
        if not settings.AutoRefresh:
            self.LeftButtonTitles.append('Refresh')
        self.drawBackground()
        self.getSearchResults()
        self.drawLabels()
        self.drawSearchResults()
        self.fillSearchResults()
        self.drawIcons()
        self.drawLeftButtons()
        self.setFocus(self.buttonLeft[0])

    def drawBackground(self):
        #Draw background
        self.addControl(xbmcgui.ControlImage(0, 0, settings.screenWidth, settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))

    def getSearchResults(self):
        global SearchVar
        global SearchVarString
        global SearchRecorded
        global LastSearch
        self.Results       = []
        self.titleList     = []
        self.SearchRef     = []
        self.SearchCount   = []
        self.sortDir       = "asc"
        if not self.isRefreshed:
            sVar = SearchVarString.replace(" ", "+")
            sVar = sVar.replace(":", "%3A")
            sVar = sVar.replace("&", "&amp;")
            sVar = sVar.replace("'", "%27")
            sVar = sVar.replace("`", "%60")
            #Read the corresponding webpage for selected search
            url  = "";
            if SearchVar == "getRecordedTV":
                if SearchVarString != "":
                    self.ScreenTitle = "Recorded TV (" + SearchVarString + ")"
                    self.SortBy      = "Date"
                else:
                    self.ScreenTitle = "Recorded TV"
                    url = webaddress + "/sagex/rpcXbmc/MediaFileAPI/GetMediaFiles/TV/sortby:" + self.SortBy.lower()
                # Still need to make the filters below work
                if self.Filter.lower() == "unwatched":
                    watched = "cleared"
                else:
                    watched = "any"
            elif SearchVar == "getMovies":
                self.ScreenTitle = "Movies"
                url = webaddress + "/sagex/rpcXbmc/Database/SearchSelectedFields/Movie/False/False/False/False/False/True/False/False/False/False/TV/sortby:" + self.SortBy.lower()
            elif SearchVar == "getIntelligent":
                self.ScreenTitle = "Sage Intelligent Choices"
                url = webaddress + "/sagex/rpcXbmc/Global/GetSuggestedIntelligentRecordings/sortby:" + self.SortBy.lower()
            elif SearchVar == "getSchedule":
                self.ScreenTitle = "Schedule"
                url = webaddress + "/sagex/rpcXbmc/Global/GetScheduledRecordings/sortby:" + self.SortBy.lower()
            elif SearchVar == "getSearchTitle":
                self.ScreenTitle = "Title Search Results: " + SearchVarString
                url = webaddress + "/sagex/rpcXbmc/Database/SearchSelectedFields/"+SearchVarString+"/False/True/False/False/False/False/False/False/False/False/TV/sortby:" + self.SortBy.lower()
            elif (SearchVar == "getOtherShowings" or SearchVar == "getOtherScheduled"):
                self.ScreenTitle = "Other Showings of " + SearchVarString
                url = webaddress + "/sagex/rpcXbmc/Database/SearchSelectedExactFields/"+SearchVarString+"/False/True/False/False/False/False/False/False/False/False/TV/sortby:" + self.SortBy.lower()
            else:
                self.ScreenTitle = "Keyword Search Results: " + SearchVarString
                url = webaddress + "/sagex/rpcXbmc/Database/SearchByText/" + sVar + "/TV/sortby:" + self.SortBy.lower()

            # We can keep a cache for recordedTV and only update it
            # the first time or if its been more than 5 minutes
            # or if its over a 30 minute barrier
            if SearchVar == "getRecordedTV":
                if SearchVarString != "":
                    for i in range(len(SearchRecorded)):
                        if SearchRecorded[i].title == SearchVarString:
                            self.Results.append(copy.copy(SearchRecorded[i]))
                else:
                    delta  = datetime.datetime.now() - LastSearch
                    refVal = datetime.timedelta(seconds=300)
                    lsmeridian = int(LastSearch.minute/30)
                    crmeridian = int(datetime.datetime.now().minute/30)
                    if len(SearchRecorded) == 0 or delta > refVal or lsmeridian != crmeridian:
                        xmldoc           = SageLib.GetAsXML(url)
                        self.Results     = SageLib.ParseIt().showsLtd(xmldoc)
                        xmldoc.unlink()
                        SearchRecorded = copy.copy(self.Results)
                        LastSearch = datetime.datetime.now()
                    else:
                        for i in range(len(SearchRecorded)):
                            self.Results.append(copy.copy(SearchRecorded[i]))
            else:
                xmldoc           = SageLib.GetAsXML(url)
                self.Results     = SageLib.ParseIt().showsLtd(xmldoc)
                xmldoc.unlink()
                if SearchVar == "getRecordedTV":
                    SearchRecorded = copy.copy(self.Results)
                    LastSearch = datetime.datetime.now()

            if SearchVar == "getOtherScheduled":
                for i in range(len(self.Results)):
                    for j in range(len(self.Results[i].airings)):
                        if not SageLib.AiringActions().isNotManualOrFavorite(self.Results[i].airing[j]):
                            self.TempPrograms.append(self.Results[i].copy())
                self.Results = self.TempPrograms
            self.BasePrograms = copy.copy(self.Results)

            # This groups the shows if sorting by title
            if self.SortBy.lower() == "title":
                self.TempResults  = []
                self.DateLabels   = []
                for i in range(len(self.Results)):
                    if i == 0:
                        self.TempResults.append(self.Results[i].copy())
                        self.DateLabels.append(self.Results[i].datestamp)
                    else:
                        if self.Results[i].title != self.Results[i-1].title:
                            self.TempResults.append(self.Results[i].copy())
                            self.DateLabels.append(self.Results[i].datestamp)
                        else:
                            self.DateLabels[len(self.DateLabels)-1] = 'More'
                self.Results = self.TempResults

    def drawLabels(self):
        #Draw Screen Title Label
        self.strActionInfo = SageLib.label(125,62,400,20)
        self.strActionInfo.setLabel(self.ScreenTitle)
        self.addControl(self.strActionInfo)
        #Draw Description Text
        self.lblTitle       = SageLib.flabel(175,360,450,20)
        self.lblDescription = SageLib.flabel(175,380,450,20)
        self.lblChannelTime = SageLib.flabel(175,400,450,20)
        self.addControl(self.lblTitle)
        self.addControl(self.lblDescription)
        self.addControl(self.lblChannelTime)


    def drawSearchResults(self):
        self.lstSearchResults = SageLib.clist(175,95,450,260)
        self.addControl(self.lstSearchResults)

    def fillSearchResults(self):
        self.lstSearchResults.reset()
        if not Emulating:
            for i in range(len(self.Results)):
                listitem = xbmcgui.ListItem()
                if self.SortBy.lower() == "title":
                    if self.DateLabels[i] != "More":
                        if (self.Results[i].episode != "" and settings.ShowEpisodeNames):
                            listitem.setLabel(str(i+1) + '. ' + self.Results[i].title + ' - "' + self.Results[i].episode + '"')
                        else:
                            listitem.setLabel(str(i+1) + '. ' + self.Results[i].title)
                    else:
                        listitem.setLabel(str(i+1) + '. ' + self.Results[i].title)
                    listitem.setLabel2(self.DateLabels[i])
                else:
                    if (self.Results[i].episode != "" and settings.ShowEpisodeNames):
                        listitem.setLabel(str(i+1) + '. ' + self.Results[i].title + ' - "' + self.Results[i].episode + '"')
                    else:
                        listitem.setLabel(str(i+1) + '. ' + self.Results[i].title)
                    listitem.setLabel2(self.Results[i].datestamp)
                self.lstSearchResults.addItem(listitem)

    def drawIcons(self):
        #Draw Watched and Archived images
        self.imgWatched = SageLib.image(178,420,20,20,settings.imgWatched)
        self.addControl(self.imgWatched)
        self.imgArchived = SageLib.image(201,420,20,20,settings.imgArchived)
        self.addControl(self.imgArchived)
        self.imgDontLike = SageLib.image(224,420,20,20,settings.imgDontLike)
        self.addControl(self.imgDontLike)
        self.imgWatched.setVisible(False)
        self.imgArchived.setVisible(False)
        self.imgDontLike.setVisible(False)

    def drawLeftButtons(self):
        global SearchVar
        global SearchVarString
        #Draw Left Buttons
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            arrowspace = ""
            if self.LeftButtonTitles[i][:4] == "Sort": arrowspace = "     "
            spacedbuttons = ["No Filter", "Unwatched", "Archived", "Movies"]
            for j in range(len(spacedbuttons)):
                if self.LeftButtonTitles[i] == spacedbuttons[j]: arrowspace = "     "
                button = SageLib.button(6,94+36*i,164,30)
                button.setLabel(arrowspace + self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)
        self.imgSortArrow = SageLib.image(16,103,12,12,settings.imgArrowRightNF)
        self.addControl(self.imgSortArrow)
        if (SearchVar == "getRecordedTV" and SearchVarString == ""):
            self.imgFilterArrow = SageLib.image(16,139,12,12,settings.imgArrowRightNF)
            self.addControl(self.imgFilterArrow)
        for i in range(len(self.LeftButtonTitles)):
            self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
            self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
            self.buttonLeft[i].controlRight(self.lstSearchResults)
        self.lstSearchResults.controlLeft(self.buttonLeft[0])

    def Refresh(self):
        global SearchVar
        global SearchVarString
        global settings
        if (SearchVar == "getRecordedTV" and SearchVarString == ""):
            if self.SortBy.lower() == "title": settings.update("RecordedTV","SortBy","Title")
            else: settings.update("RecordedTV","SortBy","Date")
        elif SearchVar == "getMovies":
            if self.SortBy.lower() == "title": settings.update("Movies", "SortBy","Title")
            else: settings.update("Movies", "SortBy","Date")
        elif SearchVar == "getSchedule":
            if self.SortBy.lower() == "title": settings.update("Schedule", "SortBy","Title")
            else: settings.update("Schedule", "SortBy","Date")
        for i in range(len(self.buttonLeft)):
            self.removeControl(self.buttonLeft[i])
        self.removeControl(self.imgSortArrow)
        self.drawLeftButtons()
        self.getSearchResults()
        self.fillSearchResults()

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK):
            self.close()
        elif (action == ACTION_PLAY):
            if SearchVar == "getRecordedTV":
                selected = self.lstSearchResults.getSelectedPosition()
                playlist = xbmc.PlayList(1)
                playlist.clear()
                for i in range(len(self.Results[selected].airings)):
                    for j in range(len(self.Results[selected].airings[i].mediaFiles)):
                        for k in range(len(self.Results[selected].airings[i].mediaFiles[j].segments)):
                            seg = self.Results[selected].airings[i].mediaFiles[j].segments[k].filePath
                            #Convert to settings.XBMCPath if they are available
                            for l in range(len(settings.RecordingPath)):
                                tempPath = settings.RecordingPath[l]
                                seg = seg.replace(tempPath,settings.XBMCPath[l])
                                seg = seg.replace("\\", "/")
                                seg = xbmc.translatePath(seg)
                            # If its not a samba mount we can't get to it directly.  It sounds odd, but do not add the s or even if it finds it the value will be 0
                            if seg.find("mb://") == 0:
                                webfile = webaddress + '/sagepublic/PlaylistGenerator?Command=Generate&pltype=m3u&fntype=url&MediaFileId=' + str(CurrentShow.airings[i].mediaFiles[j].sageDbId)
                                localfile = dirHome + 'streamplaylist.m3u'
                                SageLib.stream.downloadURL(webfile,localfile)
                                seg = localfile
                            playlist.add(seg)
                p = xbmc.Player()
                p.play(playlist)
                while(p.isPlayingVideo()):
                    for i in range(len(self.Results[selected].airings)):
                        SageLib.AiringActions().SetWatched(self.Results[selected].airings[i].sageDbId)
                    time.sleep(1)
        elif (action == ACTION_INFO):
            if self.getFocus() == self.lstSearchResults:
                selected = self.lstSearchResults.getSelectedPosition()
                CurrentShow = copy.copy(self.Results[selected])
                popup = SageProgramInfo()
                popup .doModal()
                del popup
        elif (action == ACTION_MOVE_LEFT or action == ACTION_MOVE_RIGHT
            or action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN
            or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN
            or action == ACTION_SCROLL_UP or action == ACTION_SCROLL_DOWN):

            def SubthreadUpdate(self):
                self.lblTitle.reset()
                self.lblDescription.reset()
                self.lblChannelTime.reset()
                show = self.Results[self.lstSearchResults.getSelectedPosition()]
                if show.episode != "":
                    self.lblDescription.addLabel('"' + show.episode + '" ' + show.description)
                else:
                    self.lblDescription.addLabel(show.description)
                self.lblTitle.addLabel(show.title)
                channel = ""
                for i in range(len(show.airings)):
                    channel = show.airings[i].channelId
                self.lblChannelTime.addLabel(channel + " " + show.datestamp)
                self.imgArchived.setVisible(False)
                self.imgWatched.setVisible(False)
                self.imgDontLike.setVisible(False)
                for i in range(len(show.airings)):
                    if SageLib.AiringActions().isWatched(show.airings[i]): self.imgWatched.setVisible(True)
                    if SageLib.AiringActions().isDontLike(show.airings[i]): self.imgDontLike.setVisible(True)
                    for j in range(len(show.airings[i].mediaFiles)):
                        if show.airings[i].mediaFiles[j].archived: self.imgArchived.setVisible(True)

            subThread = threading.Thread(target=SubthreadUpdate, args=[self])
            subThread.setDaemon(True)
            xbmcgui.lock()
            subThread.start()
            subThread.join(0.05)
            xbmcgui.unlock()

    def onControl(self, control):
        global CurrentShow
        global SearchVar
        global SearchVarString
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "No Filter":
                    self.isRefreshed = False
                    self.Filter = "Unwatched"
                    self.LeftButtonTitles[i] = self.Filter
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break
                elif self.LeftButtonTitles[i] == "Unwatched":
                    self.isRefreshed = False
                    self.Filter = "Movies"
                    self.LeftButtonTitles[i] = self.Filter
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break
                elif self.LeftButtonTitles[i] == "Movies":
                    self.isRefreshed = False
                    self.Filter = "No Filter"
                    self.LeftButtonTitles[i] = self.Filter
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break
                elif self.LeftButtonTitles[i] == "Sort By Date":
                    self.isRefreshed = False
                    self.LeftButtonTitles[i] = "Sort By Title"
                    self.SortBy = "Title"
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break
                elif self.LeftButtonTitles[i] == "Sort By Title":
                    self.isRefreshed = False
                    self.LeftButtonTitles[i] = "Sort By Date"
                    self.SortBy = "Date"
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break
                elif self.LeftButtonTitles[i] == "Schedule":
                    SearchVar = "getSchedule"
                    popup = SageSearchResults()
                    popup .doModal()
                    del popup
                    SearchVar = "getRecordedTV"
                    if settings.AutoRefresh:
                        self.isRefreshed = False
                        self.Refresh()
                        self.setFocus(self.buttonLeft[i])
                    break
                elif self.LeftButtonTitles[i] == "Refresh":
                    self.isRefreshed = False
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

        if control == self.lstSearchResults:
            selected = self.lstSearchResults.getSelectedPosition()
            if self.SortBy.lower() == "title":
                if self.DateLabels[selected] == "More":
                    for i in range(len(self.Results[selected].airings)):
                        if len(self.Results[selected].airings[i].mediaFiles) > 0:
                            SearchVar       = "getRecordedTV"
                        else:
                            if not SageLib.AiringActions().isNotManualOrFavorite(self.Results[selected].airing[i]):
                                SearchVar = "getOtherScheduled"
                            else:
                                SearchVar = "getOtherShowings"
                    SearchVarString = self.Results[selected].title
                    popup = SageSearchResults()
                    popup .doModal()
                    del popup
                else:
                    CurrentShow = copy.copy(self.Results[selected])
                    popup = SageProgramInfo()
                    popup .doModal()
                    del popup
            else:
                CurrentShow = copy.copy(self.Results[selected])
                popup = SageProgramInfo()
                popup .doModal()
                del popup
            if settings.AutoRefresh:
                self.isRefreshed = False
                self.Refresh()
                try: self.lstSearchResults.selectItem(selected)
                except: self.lstSearchResults.selectItem(0)
                self.lblTitle.reset()
                self.lblDescription.reset()
                self.lblChannelTime.reset()
                show = self.Results[self.lstSearchResults.getSelectedPosition()]
                if show.episode != "":
                    self.lblDescription.addLabel('"' + show.episode + '" ' + show.description)
                else:
                    self.lblDescription.addLabel(show.description)
                self.lblTitle.addLabel(show.title)
                channel = ""
                for i in range(len(show.airings)):
                    channel = show.airings[i].channelId
                self.lblChannelTime.addLabel(channel + " " + show.datestamp)
                self.imgArchived.setVisible(False)
                self.imgWatched.setVisible(False)
                self.imgDontLike.setVisible(False)
                for i in range(len(show.airings)):
                    if SageLib.AiringActions().isWatched(show.airings[i]): self.imgWatched.setVisible(True)
                    if SageLib.AiringActions().isDontLike(show.airings[i]): self.imgDontLike.setVisible(True)
                    for j in range(len(show.airings[i].mediaFiles)):
                        if show.airings[i].mediaFiles[j].archived: self.imgArchived.setVisible(True)
#End Search Reults Window

#Convert Window
class SageConvert(xbmcgui.Window):
    def __init__(self):
        global CurrentShow
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.quality = 0
        self.getTranscodeFormats
        foundMedia = False
        for i in range(len(CurrentShow.airings)):
            for j in range(len(CurrentShow.airings[i].mediaFiles)):
                foundMedia = True
                if SageLib.MFActions().isFileCurrentlyRecording(CurrentShow.airings[i].mediaFiles[j].sageDbId):
                    dialog.ok("SageTV", "Sorry, programs currently recording can not be converted.")
                    self.close()
        if not foundMedia:
            dialog.ok("SageTV", "There are no files associated with this show.")
            self.close()
        self.LeftButtonTitles = ['Convert','Cancel']
        self.drawBackground()
        self.drawLabels()
        self.drawPlusMinusButtons()
        self.drawLeftButtons()
        self.setButtonControls()
        self.setFocus(self.buttonLeft[0])

    def getTranscodeFormats(self):
        self.qualArray = SageLib.Transcode().getTranscodeFormats()

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Convert (' +  self.program.title + ')')
        #Data Labels
        self.lblQuality = SageLib.flabel(219,126,400,20)
        self.addControl(self.lblQuality)
        #Static Labels
        self.strActionInfo = SageLib.label(213,94,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Quality:')

    def drawLeftButtons(self):
        #Draw Left Buttons
        self.buttonLeftTitles = ['Convert', 'Cancel']
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(6,94+36*i,164,30)
            button.setLabel(self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)

    def drawLabels(self):
        #Quality
        self.lblQuality.reset()
        self.lblQuality.addLabel(self.qualArray[self.quality])

    def drawPlusMinusButtons(self):
        #Minus Buttons
        button = SageLib.button(530,124,30,30)
        button.setLabel("<")
        self.addControl(button)
        self.buttonMinus=button
        #Plus Buttons
        button = SageLib.button(564,124,30,30)
        button.setLabel(">")
        self.addControl(button)
        self.buttonPlus=button

    def setButtonControls(self):
        self.buttonLeft[0].controlUp(self.buttonLeft[1])
        self.buttonLeft[0].controlDown(self.buttonLeft[1])
        self.buttonLeft[0].controlRight(self.lblQuality)
        self.buttonLeft[0].controlLeft(self.buttonPlus)
        self.buttonLeft[1].controlUp(self.buttonLeft[0])
        self.buttonLeft[1].controlDown(self.buttonLeft[0])
        self.buttonLeft[1].controlRight(self.lblQuality)
        self.buttonLeft[1].controlLeft(self.buttonPlus)
        self.lblQuality.controlLeft(self.buttonLeft[0])
        self.lblQuality.controlRight(self.buttonMinus)
        self.buttonMinus.controlLeft(self.lblQuality)
        self.buttonMinus.controlRight(self.buttonPlus)
        self.buttonPlus.controlLeft(self.buttonMinus)
        self.buttonPlus.controlRight(self.buttonLeft[0])

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK): self.close()

    def onControl(self, control):
        global CurrentShow
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "Convert":
                    temp = self.qualArray[self.quality]
                    temp = temp.replace(" ", "+")
                    for j in range(len(CurrentShow.airings)):
                        for k in range(len(CurrentShow.airings[j].mediaFiles)):
                            WebHTML = SageLib.GetWebPage(webaddress + "/sage/AiringCommand?command=convert&transcodeMode="+temp+"&replaceOriginal=yes&MediaFileId="+CurrentShow.airings[j].mediaFiles[k].sageDbId)
                self.close()

        if control == self.buttonPlus:
            #Quality +
            if self.quality < (len(self.qualArray)-1):
                self.quality = self.quality + 1
            else:
                self.quality = 0
            self.drawLabels()

        if control == self.buttonMinus:
            #Quality -
            if self.quality > 0:
                self.quality = self.quality + 1
            else:
                self.quality = len(self.qualArray)-1
            self.drawLabels()
#End Convert Window

#Conversion Window
class SageConversion(xbmcgui.Window):
    def __init__(self):
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.LeftButtonTitles = ['Back']
        self.drawBackground()
        self.drawLabels()
        self.fillList()
        self.drawLeftButtons()
        self.setFocus(self.buttonLeft[0])

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Conversion Queue')

    def drawLeftButtons(self):
        #Draw Left Buttons
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(6,94+36*i,164,30)
            button.setLabel(self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)

    def drawLabels(self):
        #Draw Listings List
        self.lstPrograms = SageLib.clist(178,94,450,260)
        self.addControl(self.lstPrograms)

    def fillList(self):
        # First clear completed ones
        sageLib.Transcode().clearTranscodedJobs()
        # Get the jobs still running or queued
        jobIDs = SageLib.Transcode().getTranscodeJobs()
        for i in range(len(jobIDs)):
            # Get the source file
            shows = SageLib.Transcode().getTranscodeJobSourceFile(jobIDs[i])
            # Get the status
            status = SageLib.Transcode().getTranscodeJobStatus(jobIDs[i])
            for j in range(len(shows)):
                self.lstPrograms.addItem(xbmcgui.ListItem(label=status+": "+shows[i].title+" - "+shows[i].episode))

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK): self.close()

    def onControl(self, control):
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                self.close()
#End Conversion Window

#PROGRAM INFO WINDOW
class SageProgramInfo(xbmcgui.Window):

    def __init__(self):
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.LeftButtonTitles = []
        self.buttonLeft       = []
        self.imgRec           = []
        self.refreshed        = False
        self.drawBackground()
        self.Refresh()
        self.setFocus(self.buttonLeft[0])

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Show Details' )

    def drawLabels(self):
        global CurrentShow
        #First Run and subtitle
        self.lblFirstRun = SageLib.flabel(178,120,430,20)
        self.addControl(self.lblFirstRun)
        tempVal = CurrentShow.episode
        if CurrentShow.episode != "":
            tempVal = tempVal + " - "
        if SageLib.ShowActions().isShowFirstRun(CurrentShow.epgId): self.lblFirstRun.addLabel(tempVal+"First Run")
        else: self.lblFirstRun.addLabel(tempVal+"Rerun")
        #Date and Time
        self.lblDateTime = SageLib.flabel(178,142,430,20)
        self.addControl(self.lblDateTime)
        self.lblDateTime.addLabel(CurrentShow.datestamp+" "+CurrentShow.timestamp)
        #Channel
        self.lblChannel = SageLib.flabel(178,162,430,20)
        self.addControl(self.lblChannel)
        for i in range(len(CurrentShow.airings)):
            self.lblChannel.addLabel(CurrentShow.airings[i].channelId)
        #File Format
        self.lblFormat = SageLib.flabel(178,182,430,20)
        self.addControl(self.lblFormat)
        for i in range(len(CurrentShow.airings)):
            if len(CurrentShow.airings[i].mediaFiles) > 0:
                self.lblFormat.addLabel(SageLib.MFActions().getMediaFileEncoding(CurrentShow.airings[i].mediaFiles[0].sageDbId))
            break
        #Description
        self.DescriptionBox = xbmcgui.ControlTextBox(settings.scw(178+settings.x), settings.sch(204+settings.y), settings.scw(430), settings.sch(300), 'font14', settings.colorBold)
        self.addControl(self.DescriptionBox)
        desc = CurrentShow.description + "\n\n"
        if len(CurrentShow.advisoryList) > 0:
            desc = desc + "Advisories: "
        for i in range(len(CurrentShow.advisoryList)):
            desc = desc + CurrentShow.advisoryList[i] + ","
        if len(CurrentShow.advisoryList) > 0:
            desc = desc + "\n"
        for i in range(len(CurrentShow.peopleList)):
            desc = desc + CurrentShow.peopleList[i].person + "(" + CurrentShow.peopleList[i].role + ")\n"
        self.DescriptionBox.setText(desc)

    def drawLeftButtons(self):
        global CurrentShow
        self.LeftButtonTitles = []
        self.buttonLeft       = []
        if not self.recorded:
            if self.setToRecord:
                self.LeftButtonTitles.append('Recording Settings')
                self.LeftButtonTitles.append('Cancel Recording')
            else:
                self.LeftButtonTitles.append('Record')
                self.LeftButtonTitles.append('Advanced Record')
        else:
            self.LeftButtonTitles.append('Watch')
            if self.recording:
                self.LeftButtonTitles.append('Recording Settings')
                self.LeftButtonTitles.append('Cancel Recording')
        if self.favoriteId > 0:
            self.LeftButtonTitles.append('Favorites Settings')
        else:
            self.LeftButtonTitles.append('Record Series')
        self.LeftButtonTitles.append('Other Showings')

        if self.watched: self.LeftButtonTitles.append('Clear Watched')
        else: self.LeftButtonTitles.append('Set Watched')

        if self.dontlike: self.LeftButtonTitles.append("Clear Don't Like")
        else: self.LeftButtonTitles.append("Set Don't Like")

        if self.recorded:
            if self.archived: self.LeftButtonTitles.append('Unarchive')
            else: self.LeftButtonTitles.append('Archive')
            self.LeftButtonTitles.append('Delete')
            self.LeftButtonTitles.append('Convert')

        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(6,94+36*i,164,30)
            button.setLabel(self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)
        for i in range(len(self.LeftButtonTitles)):
            self.buttonLeft[i].controlUp(self.buttonLeft[(i - 1) % len(self.LeftButtonTitles)])
            self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
            self.buttonLeft[i].controlRight(self.DescriptionBox)
        self.DescriptionBox.controlLeft(self.buttonLeft[0])

    def drawIcons(self):
        self.imgRec = []
        ProgramTitleXadjust = 0
        if self.archived:
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgLock))
            ProgramTitleXadjust = 34
        if self.recording:
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgCurRec))
            ProgramTitleXadjust = ProgramTitleXadjust + 34
        if self.favoriteId > 0:
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgSeriesRec))
            ProgramTitleXadjust = ProgramTitleXadjust + 64
        elif self.setToRecord:
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgManualRec))
            ProgramTitleXadjust = ProgramTitleXadjust + 34
        if self.watched:
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgWatchedS))
            ProgramTitleXadjust = ProgramTitleXadjust + 34
        if self.dontlike:
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgDontLikeS))
            ProgramTitleXadjust = ProgramTitleXadjust + 34
        if self.parentalRating != "":
            self.imgRec.append(SageLib.image(178+ProgramTitleXadjust,90,30,30,settings.imgRating + self.parentalRating + '.gif'))
            ProgramTitleXadjust = ProgramTitleXadjust + 34
        for i in range(len(self.imgRec)):
            self.addControl(self.imgRec[i])
        self.lblTitle = SageLib.flabel(178+ProgramTitleXadjust,90,300,20)
        self.addControl(self.lblTitle)
        self.lblTitle.addLabel(CurrentShow.title)

    def Refresh(self):
        global CurrentShow
        # Get the full information for this show
        if len(CurrentShow.airings) == 0:
            dialog.ok("SageTV","There is no information to display for this show")
            close()
        # Try to get down to the media files level.  If not possible get to the airing level
        tempShows = SageLib.AiringActions().getMediaFileForAiring(CurrentShow.airings[0].sageDbId)
        if len(tempShows) == 0:
            tempShows = SageLib.AiringActions().getAiringForID(CurrentShow.airings[0].sageDbId)
        if len(tempShows) == 0:
            dialog.ok("SageTV","There is no information to display for this show")
            close()
        else:
            if len(tempShows[0].airings) == 0:
                dialog.ok("SageTV","There is no information to display for this show")
                close()
            else:
                CurrentShow = copy.copy(tempShows[0])
        self.recorded       = False
        self.recording      = False
        self.setToRecord    = False
        self.watched        = False
        self.dontlike       = False
        self.archived       = False
        self.parentalRating = ""
        self.favoriteId     = 0
        for i in range(len(CurrentShow.airings)):
            if not SageLib.AiringActions().isNotManualOrFavorite(CurrentShow.airings[i].sageDbId):
                self.setToRecord = True
            if SageLib.AiringActions().isWatched(CurrentShow.airings[i].sageDbId):
                self.watched = True
            if SageLib.AiringActions().isDontLike(CurrentShow.airings[i].sageDbId):
                self.dontlike = True
            if len(CurrentShow.airings[i].mediaFiles) > 0:
                self.recorded = True
            if CurrentShow.airings[i].parentalRating != "":
                self.parentalRating = CurrentShow.airings[i].parentalRating
            self.favoriteId = CurrentShow.airings[i].favoriteId
            for j in range(len(CurrentShow.airings[i].mediaFiles)):
                if SageLib.MFActions().isFileCurrentlyRecording(CurrentShow.airings[i].mediaFiles[j].sageDbId):
                    self.recording = True
                if CurrentShow.airings[i].mediaFiles[j].archived: self.archived = True
        if self.refreshed:
            for i in range(len(self.buttonLeft)):
                self.removeControl(self.buttonLeft[i])
            for i in range(len(self.imgRec)):
                self.removeControl(self.imgRec[i])
            self.removeControl(self.lblTitle)
            self.removeControl(self.lblFirstRun)
            self.removeControl(self.lblDateTime)
            self.removeControl(self.lblChannel)
            self.removeControl(self.lblFormat)
            self.removeControl(self.DescriptionBox)
        else:
            self.refreshed = True
        self.drawLabels()
        self.drawIcons()
        self.drawLeftButtons()

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK): self.close()

    def onControl(self, control):
        global CurrentShow
        global SearchVar
        global SearchVarString
        pt = CurrentShow.title.replace(" ", "+")
        pt = pt.replace(":", "%3A")

        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "Watch":
                    #Watch
                    playlist = xbmc.PlayList(1)
                    for i in range(len(CurrentShow.airings)):
                        for j in range(len(CurrentShow.airings[i].mediaFiles)):
                            for k in range(len(CurrentShow.airings[i].mediaFiles[j].segments)):
                                seg = CurrentShow.airings[i].mediaFiles[j].segments[k].filePath
                                #Convert to settings.XBMCPath if they are available
                                for l in range(len(settings.RecordingPath)):
                                    tempPath = settings.RecordingPath[l]
                                    seg = seg.replace(tempPath,settings.XBMCPath[l])
                                    seg = seg.replace("\\", "/")
                                    seg = xbmc.translatePath(seg)
                                # If its not a samba mount we can't get to it directly.  It sounds odd, but do not add the s or even if it finds it the value will be 0
                                if seg.find("mb://") == 0:
                                    webfile = webaddress + '/sagepublic/PlaylistGenerator?Command=Generate&pltype=m3u&fntype=url&MediaFileId=' + str(CurrentShow.airings[i].mediaFiles[j].sageDbId)
                                    localfile = dirHome + 'streamplaylist.m3u'
                                    SageLib.stream.downloadURL(webfile,localfile)
                                    seg = localfile
                                playlist.add(seg)

                    p = xbmc.Player()
                    p.play(playlist)

                    while(p.isPlayingVideo()):
                        for i in range(len(CurrentShow.airings)):
                            SageLib.AiringActions().SetWatched(CurrentShow.airings[i].sageDbId)
                        time.sleep(1)

                elif self.LeftButtonTitles[i] == "Record":
                    for i in range(len(CurrentShow.airings)):
                        SageLib.AiringActions().setRecord(CurrentShow.airings[i].sageDbId)
                    self.setToRecord = True
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Recording Settings":
                    popup = SageRecSettings()
                    popup .doModal()
                    del popup

                elif self.LeftButtonTitles[i] == "Advanced Record":
                    popup = SageRecSettings()
                    popup .doModal()
                    del popup
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])

                elif self.LeftButtonTitles[i] == "Cancel Recording":
                    for i in range(len(CurrentShow.airings)):
                        self.setToRecord = SageLib.AiringActions().cancelRecord(CurrentShow.airings[i].sageDbId)
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Record Series":
                    WebHTML = SageLib.FavoriteActions().addFavorite(CurrentShow.title, "true", "true", "", "", "", "", "", "", "", "", "", "", "")
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Series Settings":
                    global FavoriteId
                    for i in range(len(CurrentShow.airings)):
                        FavoriteId = CurrentShow.airings[i].favoriteId
                    popup = SageSeriesSettings()
                    popup .doModal()
                    del popup
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Other Showings":
                    SearchVar       = "getOtherShowings"
                    SearchVarString = CurrentShow.title
                    popup           = SageSearchResults()
                    popup .doModal()
                    del popup

                elif self.LeftButtonTitles[i] == "Convert":
                    popup = SageConvert()
                    popup .doModal()
                    del popup

                elif self.LeftButtonTitles[i] == "Set Watched":
                    dialog.ok("","Pre loop")
                    for i in range(len(CurrentShow.airings)):
                        dialog.ok(str(i), "In loop")
                        self.watched = SageLib.AiringActions().setWatched(CurrentShow.airings[i].sageDbId)
                        dialog.ok("","airing set to watched")
                    self.Refresh()
                    dialog.ok("","Refreshed")
                    self.setFocus(self.buttonLeft[i])
                    dialog.ok("","all done")
                    break

                elif self.LeftButtonTitles[i] == "Clear Watched":
                    for i in range(len(CurrentShow.airings)):
                        self.watched = SageLib.AiringActions().clearWatched(CurrentShow.airings[i].sageDbId)
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Set Don't Like":
                    for i in range(len(CurrentShow.airings)):
                        self.dontlike = SageLib.AiringActions().setDontLike(CurrentShow.airings[i].sageDbId)
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Clear Don't Like":
                    for i in range(len(CurrentShow.airings)):
                        self.dontlike = SageLib.AiringActions().clearDontLike(CurrentShow.airings[i].sageDbId)
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Archive":
                    for i in range(len(CurrentShow.airings)):
                        for j in range(len(CurrentShow.airings[i].mediaFiles)):
                            self.archived = SageLib.MFActions().MoveFileToLibrary(CurrentShow.airings[i].mediaFiles[j].sageDbId)
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Unarchive":
                    for i in range(len(CurrentShow.airings)):
                        for j in range(len(CurrentShow.airings[i].mediaFiles)):
                            self.archived = SageLib.MFActions().MoveTVFileOutOfLibrary(CurrentShow.airings[i].mediaFiles[j].sageDbId)
                    self.Refresh()
                    self.setFocus(self.buttonLeft[i])
                    break

                elif self.LeftButtonTitles[i] == "Delete":
                    if dialog.yesno("SageTV", "Are you sure you want to delete \n" + CurrentShow.title + " " + CurrentShow.episode + "?"):
                        for i in range(len(CurrentShow.airings)):
                            for j in range(len(CurrentShow.airings[i].mediaFiles)):
                                SageLib.MFActions().delete(CurrentShow.airings[i].mediaFiles[j].sageDbId)
                        time.sleep(1)
                        self.close()

#RECORDING SETTINGS
class SageRecSettings(xbmcgui.Window):
    def __init__(self):
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        global CurrentShow
        if len(CurrentShow.airings) > 0:
            self.airing = CurrentShow.airings[0]
        else:
            dialog.ok("SageTV","There is no airing to set recordings for")
            close()
        self.recording   = False
        self.setToRecord = False
        self.recorded    = False
        if not SageLib.AiringActions().isNotManualOrFavorite(self.airing.sageDbId):
            self.setToRecord = True
        for j in range(len(self.airing.mediaFiles)):
            self.recorded = True
            if SageLib.MFActions().isFileCurrentlyRecording(self.airing.mediaFiles[j].sageDbId):
                self.recording = True
        if self.recording:
            dialog.ok("SageTV", "Sorry, programs currently recording can't be modified.")
            self.close()
        if not self.setToRecord:
            self.setRecord()
        self.quality   = 0;
        self.getTranscodeFormats()
        self.endpadding       = SageLib.AiringActions().getEndPadding(self.airing.sageDbId)
        self.startpadding     = SageLib.AiringActions().getStartPadding(self.airing.sageDbId)
        self.LeftButtonTitles = ['Save','Cancel Recording','Back']
        self.drawBackground()
        self.drawLabels()
        self.drawPlusMinusButtons()
        self.drawLeftButtons()
        self.setFocus(self.buttonLeft[0])

    def getTranscodeFormats(self):
        self.qualArray = SageLib.Transcode().getTranscodeFormats()
        self.qualArray.insert(0, 'Default')
        qualityName = SageLib.AiringActions().getRecordingQuality(self.airing.sageDbId)
        # Loop through all the qaulities and mark the appropriate one
        for i in range(len(self.qualArray)):
            if self.qualArray[i] == qualityName:
                self.quality = i

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Recording Options (' +  CurrentShow.title + ')')
        #Data Labels
        self.lblQuality = SageLib.flabel(219,126,400,20)
        self.addControl(self.lblQuality)
        self.lblStop = SageLib.flabel(219,192,400,20)
        self.addControl(self.lblStop)
        self.lblStart = SageLib.flabel(219,258,400,20)
        self.addControl(self.lblStart)
        #Static Labels
        self.strActionInfo = SageLib.label(213,94,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Quality:')
        self.strActionInfo = SageLib.label(213,160,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Stop:')
        self.strActionInfo = SageLib.label(213,226,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Start:')

    def drawLeftButtons(self):
        #Draw Left Buttons
        if not self.setToRecord: self.buttonLeftTitles = ['Record','Cancel Recording','Back']
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(6,94+36*i,165,30)
            button.setLabel(self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)
        for i in range(len(self.LeftButtonTitles)):
            self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
            self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
            self.buttonLeft[i].controlRight(self.buttonMinus[0])
        for i in range(3):
            self.buttonMinus[i].controlLeft(self.buttonLeft[0])
            self.buttonPlus[i].controlRight(self.buttonLeft[0])

    def drawLabels(self):
        #Quality
        self.lblQuality.reset()
        self.lblQuality.addLabel(self.qualArray[self.quality])
        #Stop
        self.lblStop.reset()
        if self.endpadding < 0:
            stoplabel = str(-self.endpadding) + " minute(s) before"
        elif self.endpadding == 0:
            stoplabel = "On Time"
        else:
            stoplabel = str(self.endpadding) + " minute(s) after"
        self.lblStop.addLabel(stoplabel)
        #Start
        self.lblStart.reset()
        if self.startpadding < 0:
            startlabel = str(-self.startpadding) + " minute(s) before"
        elif self.startpadding == 0:
            startlabel = "On Time"
        else:
            startlabel = str(self.startpadding) + " minute(s) after"
        self.lblStart.addLabel(startlabel)

    def drawPlusMinusButtons(self):
        self.buttonPlus = []
        self.buttonMinus = []
        for i in range(3):
            #Minus Buttons
            button = SageLib.button(530,124+66*i,30,30)
            button.setLabel("-")
            self.addControl(button)
            self.buttonMinus.append(button)
            #Plus Buttons
            button = SageLib.button(564,124+66*i,30,30)
            button.setLabel("+")
            self.addControl(button)
            self.buttonPlus.append(button)
        for i in range(3):
            self.buttonPlus[i].controlUp(self.buttonPlus[i - 1])
            self.buttonPlus[i].controlDown(self.buttonPlus[(i + 1) % 3])
            self.buttonPlus[i].controlLeft(self.buttonMinus[i])
            self.buttonMinus[i].controlUp(self.buttonMinus[i - 1])
            self.buttonMinus[i].controlDown(self.buttonMinus[(i + 1) % 3])
            self.buttonMinus[i].controlRight(self.buttonPlus[i])

    def setQualityPadding(self):
        #Set Quality
        qualName = self.qualArray[self.quality]
        if qualName == "Default":
            qualName = SageLib.AiringActions().getDefaultRecordingQuality()
        SageLib.AiringActions.setRecordingQuality(self.airing.sageDbId, qualName)
        #Set Padding
        tempStart = SageLib.AiringActions().getSchedStart(self.airing.sageDbId) + self.startpadding*60
        tempEnd   = SageLib.AiringActions().getSchedEnd(self.airing.sageDbId) + self.endpadding*60
        SageLib.AiringActions.setRecordingTimes(self.airing.sageDbId, tempStart, tempEnd)

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK):
            self.close()

    def onControl(self, control):
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "Record":
                    SageLib.AiringActions.setRecord(self.airing.sageDbId)
                    self.setQualityPadding()
                    self.close()
                elif self.LeftButtonTitles[i] == "Save":
                    #Save
                    self.setQualityPadding()
                    self.close()
                elif self.LeftButtonTitles[i] == "Cancel Recording":
                    #Cancel
                    if dialog.yesno("SageTV", "Are you sure you want to cancel this recording?"):
                        SageLib.AiringActions.cancelRecord(self.airing.sageDbId)
                        self.close()
                elif self.LeftButtonTitles[i] == "Back":
                    self.close()
        for i in range(3):
            if control == self.buttonPlus[i]:
                #Quality +
                if i == 0:
                    self.quality = self.quality + 1
                    if (self.quality == len(self.qualArray)):
                        self.quality = 0
                    self.drawLabels()
                #Stop +
                elif i == 1:
                    self.endpadding = self.endpadding + 1
                    self.drawLabels()
                #Start +
                elif i == 2:
                    self.startpadding = self.startpadding + 1
                    self.drawLabels()
            if control == self.buttonMinus[i]:
                #Quality -
                if i == 0:
                    self.quality = self.quality - 1
                    if (self.quality == -1):
                        self.quality = len(self.qualArray)-1
                    self.drawLabels()
                #Stop -
                elif i == 1:
                    self.endpadding = self.endpadding - 1
                    self.drawLabels()
                #Start -
                elif i == 2:
                    self.startpadding = self.startpadding - 1
                    self.drawLabels()
#End SageRecSettings

#RECORD SERIES SETTINGS
class SageSeriesSettings(xbmcgui.Window):
    def __init__(self):
        self.setCoordinateResolution(settings.Resolution)
        global FavoriteId
        if Emulating: xbmcgui.Window.__init__(self)
        self.series = SageLib.FavoriteActions().getFavorite(FavoriteId)
        if FavoriteId != 0:
            self.LeftButtonTitles = ['Save','Cancel','Cancel Series','Other Showings','Back']
        else:
            self.LeftButtonTitles = ['Save Series','Back']
        self.drawBackground()
        self.drawLabels()
        self.drawPlusMinusButtons()
        self.drawLeftButtons()
        self.setFocus(self.buttonLeft[0])

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Series Settings (' +  self.series.title + ')')
        #Data Labels
        self.lblFirstRuns = SageLib.flabel(219,120,400,20)
        self.addControl(self.lblFirstRuns)
        self.lblQuality = SageLib.flabel(219,180,400,20)
        self.addControl(self.lblQuality)
        self.lblStop = SageLib.flabel(219,240,400,20)
        self.addControl(self.lblStop)
        self.lblStart = SageLib.flabel(219,300,400,20)
        self.addControl(self.lblStart)
        self.lblKeep = SageLib.flabel(219,360,400,20)
        self.addControl(self.lblKeep)
        self.lblKeepupto = SageLib.flabel(219,420,400,20)
        self.addControl(self.lblKeepupto)
        #Static Labels
        self.strActionInfo = SageLib.label(213,94,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Show Type:')
        self.strActionInfo = SageLib.label(213,154,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Quality:')
        self.strActionInfo = SageLib.label(213,214,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Stop:')
        self.strActionInfo = SageLib.label(213,274,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Start:')
        self.strActionInfo = SageLib.label(213,334,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Keep:')
        self.strActionInfo = SageLib.label(213,394,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Keep up to:')

    def drawLeftButtons(self):
        #Draw Left Buttons
        self.buttonLeft = []
        for i in range(len(self.LeftButtonTitles)):
            button = SageLib.button(6,94+36*i,165,30)
            button.setLabel(self.LeftButtonTitles[i])
            self.addControl(button)
            self.buttonLeft.append(button)
        for i in range(len(self.LeftButtonTitles)):
            self.buttonLeft[i].controlUp(self.buttonLeft[i - 1])
            self.buttonLeft[i].controlDown(self.buttonLeft[(i + 1) % len(self.LeftButtonTitles)])
            self.buttonLeft[i].controlRight(self.buttonMinus[0])
        for i in range(6):
            self.buttonMinus[i].controlLeft(self.buttonLeft[0])
            self.buttonPlus[i].controlRight(self.buttonLeft[0])

    def drawLabels(self):
        #Show Type
        self.lblFirstRuns.reset()
        self.lblFirstRuns.addLabel(self.series.firstruns)
        #Quality
        self.lblQuality.reset()
        self.lblQuality.addLabel(self.series.quality)
        #Stop
        self.lblStop.reset()
        if self.series.endpadding == -1:
            stoplabel = "1 minute before"
        elif self.series.endpadding < -1:
            stoplabel = str(-self.series.endpadding) + " minutes before"
        elif self.series.endpadding == 0:
            stoplabel = "On Time"
        elif self.series.endpadding == 1:
            stoplabel = "1 minute after"
        else:
            stoplabel = str(self.series.endpadding) + " minutes after"
        self.lblStop.addLabel(stoplabel)
        #Start
        self.lblStart.reset()
        if self.series.startpadding == -1:
            startlabel = "1 minute before"
        elif self.series.startpadding < -1:
            startlabel = str(-self.series.startpadding) + " minutes before"
        elif self.series.startpadding == 0:
            startlabel = "On Time"
        elif self.series.startpadding == 1:
            startlabel = "1 minute after"
        else:
            startlabel = str(self.series.startpadding) + " minutes after"
        self.lblStart.addLabel(startlabel)
        #Keep
        self.lblKeep.reset()
        if self.series.autodelete == "true":
            self.lblKeep.addLabel("Until space is needed")
        else:
            self.lblKeep.addLabel("Until I delete")
        #Keep up to
        self.lblKeepupto.reset()
        if self.series.keepatmost == 0:
            self.lblKeepupto.addLabel("As many as possible")
        else:
            self.lblKeepupto.addLabel(str(self.series.keepatmost))

    def drawPlusMinusButtons(self):
        self.buttonPlus = []
        self.buttonMinus = []
        for i in range(6):
            #Minus Buttons
            button = SageLib.button(530,124+60*i,30,30)
            button.setLabel("-")
            self.addControl(button)
            self.buttonMinus.append(button)
            #Plus Buttons
            button = SageLib.button(564,124+60*i,30,30)
            button.setLabel("+")
            self.addControl(button)
            self.buttonPlus.append(button)
        for i in range(6):
            self.buttonPlus[i].controlUp(self.buttonPlus[i - 1])
            self.buttonPlus[i].controlDown(self.buttonPlus[(i + 1) % 6])
            self.buttonPlus[i].controlLeft(self.buttonMinus[i])
            self.buttonMinus[i].controlUp(self.buttonMinus[i - 1])
            self.buttonMinus[i].controlDown(self.buttonMinus[(i + 1) % 6])
            self.buttonMinus[i].controlRight(self.buttonPlus[i])

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK):
            self.close()

    def onControl(self, control):
        global SearchVar
        global SearchVarString
        temptitle = self.series.title.replace(" ", "+")
        temptitle = temptitle.replace("&", "%26")
        temptitle = temptitle.replace("`", "%60")
        temptitle = temptitle.replace("'", "%27")
        for i in range(len(self.LeftButtonTitles)):
            if control == self.buttonLeft[i]:
                if self.LeftButtonTitles[i] == "Save":
                    #Save
                    if self.series.startpadding < 0:
                        startpadtype = "earlier"
                        startpad = -self.series.startpadding
                    else:
                        startpadtype = "later"
                        startpad = self.series.startpadding
                    if self.series.endpadding < 0:
                        endpadtype = "earlier"
                        endpad = -self.series.endpadding
                    else:
                        endpadtype = "later"
                        endpad = self.series.endpadding
                    quality = self.series.quality.replace(" ", "+")

                    Base_URL = webaddress + "/sage/FavoriteCommand?command=Update&FavoriteId=" + str(self.series.favoriteid) + "&title=" + temptitle + "&run=" + self.series.firstruns.replace(" ", "+") + "&autodelete=" + self.series.autodelete + "&keepatmost=" + str(self.series.keepatmost) + "&startpad=" + str(startpad) + "&StartPadOffsetType=" + startpadtype + "&endpad=" + str(endpad) + "&EndPadOffsetType=" + endpadtype + "&quality=" + quality + "&favoritepriorityrelation=" + self.series.priorityrelation + "&relativefavoriteid=" + self.series.relativefavoriteid
                    WebSock = urllib.urlopen(Base_URL)  # Opens a 'Socket' to URL
                    WebHTML = WebSock.read()            # Reads Contents of URL and saves to Variable
                    WebSock.close()                     # Closes connection to url
                    if not WebHTML.find('Applied command: Update on favorite') > 0:
                        dialog.ok("SageTV","Error Updating Series Settings")
                    self.close()
                elif self.LeftButtonTitles[i] == "Back":
                    self.close()
                elif self.LeftButtonTitles[i] == "Cancel Series":
                    #Cancel Series
                    if dialog.yesno("SageTV", "Are you sure you want to cancel series for \n" + self.series.title + "?"):
                        Base_URL = webaddress + "/sage/FavoriteCommand?command=Remove&FavoriteId=" + str(self.series.favoriteid)
                        WebSock = urllib.urlopen(Base_URL)  # Opens a 'Socket' to URL
                        WebHTML = WebSock.read()            # Reads Contents of URL and saves to Variable
                        WebSock.close()                     # Closes connection to url
                        self.close()
                elif self.LeftButtonTitles[i] == "Other Showings":
                    #Other Showings
                    SearchVar = "getOtherShowings"
                    SearchVarString = self.series.title
                    #self.close()
                    popup = SageSearchResults()
                    popup .doModal()
                    del popup

        for i in range(6):
            if control == self.buttonPlus[i]:
                #FirstRuns +
                if i == 0:
                    fruns = ['First Runs and ReRuns', 'First Runs', 'ReRuns']
                    for j in range(len(fruns)):
                        if fruns[j] == self.series.firstruns:
                            if j < len(fruns) - 1:
                                self.series.firstruns = fruns[j + 1]
                                break
                            else:
                                self.series.firstruns = fruns[0]
                                break
                    self.drawLabels()
                #Quality +
                if i == 1:
                    for j in range(len(self.series.allqualities)):
                        if self.series.allqualities[j] == self.series.quality:
                            if j > 0:
                                self.series.quality = self.series.allqualities[j - 1]
                                break
                    self.drawLabels()
                #Stop +
                elif i == 2:
                    self.series.endpadding = self.series.endpadding + 1
                    self.drawLabels()
                #Start +
                elif i == 3:
                    self.series.startpadding = self.series.startpadding + 1
                    self.drawLabels()
                #Keep +
                elif i == 4:
                    if self.series.autodelete == "true": self.series.autodelete = "false"
                    else: self.series.autodelete = "true"
                    self.drawLabels()
                #Keep up to +
                elif i == 5:
                    if self.series.keepatmost < 15:
                        self.series.keepatmost = self.series.keepatmost + 1
                    else:
                        self.series.keepatmost = 0
                    self.drawLabels()

            if control == self.buttonMinus[i]:
                #FirstRuns -
                if i == 0:
                    fruns = ['First Runs and ReRuns', 'First Runs', 'ReRuns']
                    for j in range(len(fruns)):
                        if fruns[j] == self.series.firstruns:
                            if j > 0:
                                self.series.firstruns = fruns[j - 1]
                                break
                            else:
                                self.series.firstruns = fruns[len(fruns) - 1]
                                break
                    self.drawLabels()
                #Quality -
                if i == 1:
                    for j in range(len(self.series.allqualities)):
                        if self.series.allqualities[j] == self.series.quality:
                            if j < len(self.series.allqualities) - 1:
                                self.series.quality = self.series.allqualities[j + 1]
                                break
                            else:
                                break
                    self.drawLabels()
                #Stop -
                elif i == 2:
                    self.series.endpadding = self.series.endpadding - 1
                    self.drawLabels()
                #Start -
                elif i == 3:
                    self.series.startpadding = self.series.startpadding - 1
                    self.drawLabels()
                #Keep -
                elif i == 4:
                    if self.series.autodelete == "true": self.series.autodelete = "false"
                    else: self.series.autodelete = "true"
                    self.drawLabels()
                #Keep up to -
                elif i == 5:
                    if self.series.keepatmost > 0:
                        self.series.keepatmost = self.series.keepatmost - 1
                    else:
                        self.series.keepatmost = 15
                    self.drawLabels()
#End SageSeriesSettings

# Grid View Guide NEEDS WORK
class SageGridGuide(xbmcgui.Window):

    def __init__(self):
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.drawBackground()
        self.channel  = []
        self.entry    = []
        self.indexY   = 0
        year  = int(datetime.datetime.today().year)
        month = int(datetime.datetime.today().month)
        day   = int(datetime.datetime.today().day)
        hour  = int(datetime.datetime.today().hour)
        if int(datetime.datetime.today().minute) > 29:
            self.refDate = datetime.datetime(year,month,day,hour,30)
        else :
            self.refDate = datetime.datetime(year,month,day,hour,0)
        self.epochStart = time.mktime(self.refDate.timetuple())
        self.getInformation()
        self.drawEntries()

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Guide Grid Format')

    def getInformation(self):
        #TimeRange is only 24 hours right now
        WebXML = SageLib.GetWebPage(webaddress + "/sage/Search?TimeRange=24&SearchString=&searchType=Airings&Video=on&DVD=on&search_fields=title&filename=&Categories=**Any**&Channels=**Any**&watched=any&dontlike=any&favorite=any&firstruns=any&hdtv=any&archived=any&manrec=any&autodelete=any&partials=none&sort1=airdate_asc&sort2=none&grouping=None&pagelen=inf&xml=yes")
        xmldoc = WebXMLContent(WebXML)
        listings = SageLib.ParseIt().showsLtd(xmldoc)
        xmldoc.unlink()
        # Set the channels column
        for chan in self.channel:
            emptyArray = []
            self.entry.append(emptyArray)
        for listing in listings:
            #Get the channel index and add the listing there
            for i in range(len(self.channel)):
                if self.channel[i].channelNumber+" "+self.channel[i].channelName == listing.AiringChannelId:
                    self.entry[i].append(listing)

    def drawEntries(self):
        endY = self.indexY + 12
        if len(self.channel) <= endY:
            endY = len(self.channel) - 1

        self.gridControl = [] # Stores all the controls for the shows in the grid
        self.chanControl = [] # Stores all the channels
        self.gridInfo    = [] # Stores all the media ids
        # Iterate through each line
        for i in range(self.indexY, endY):
            # Make a control array for the channel entries
            gridEntryControl = []
            gridEntryInfo    = []
            # Draw the channel (fadelabel is not the right choice)
            self.chanControl.append( SageLib.label(10,100+i*30,115,25) )
            idx = len(self.chanControl)-1
            self.addControl( self.chanControl[idx] )
            self.chanControl[idx].setLabel(self.channel[i].channelNumber+" "+self.channel[i].channelName)
            # Iterate through each item in the line
            for entry in self.entry[i]:
                duration = int(entry.AiringDuration)
                sStart   = time.mktime(entry.startTime.timetuple())
                sEnd     = sStart + duration
                diff     = sStart - self.epochStart
                if (sEnd >= self.epochStart and sStart <= self.epochStart+(120*60)): # between reftime and 120 minutes
                    if diff < 0:
                        duration = int((duration + diff)/60) #Since we don't want to make the width too big
                        diff = 0 #It should never be negative
                    else:
                        diff     = int(diff / 60)
                        duration = int(duration / 60)
                    # Need to shrink the title
                    labelLen = len(entry.title)
                    maxStrLen = int(duration/2.3) #Only works with font14
                    if maxStrLen < labelLen: labelLen = maxStrLen
                    labelStr = entry.title[0:labelLen]
                    gridEntryInfo.append(str(entry.AiringSageDbId))
                    tempentry = SageLib.button(150+4*diff,100+i*30,4*duration,25)
                    tempentry.setLabel(labelStr)
                    gridEntryControl.append(tempentry)
                    self.addControl(gridEntryControl[len(gridEntryControl)-1])
            self.gridControl.append(gridEntryControl)
            self.gridInfo.append(gridEntryInfo)

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK): self.close()

    def refresh(self):
        self.getInformation()

    def onControl(self, control):
        for i in range(len(self.gridControl)):
            for j in range(len(self.gridControl[i])):
                if control == self.gridControl[i][j]:
                    SelectedProgram = SageLib.Program(0, self.gridInfo[i][j])
                    # Why is this coming up blank? Verified that SelectedProgram is valid here, but turns blank in SageProgramInfo
                    popup = SageProgramInfo()
                    popup .doModal()
                    del popup

#THE GUIDE
class SageGuide(xbmcgui.Window):
    def __init__(self):
        self.ChannelPrograms = []
        self.setCoordinateResolution(settings.Resolution)
        if Emulating: xbmcgui.Window.__init__(self)
        self.drawBackground()
        self.drawChannelsPrograms()
        self.drawIcons()
        self.fillChannels()
        self.setFocus(self.lstChannels)

    def drawBackground(self):
        #Background and Labels Draw
        self.addControl(xbmcgui.ControlImage(0,0,settings.screenWidth,settings.screenHeight, settings.imgBackground))
        self.addControl(SageLib.image(5,30,400,70,settings.imgTVLogo))
        self.strActionInfo = SageLib.label(126,62,400,20)
        self.addControl(self.strActionInfo)
        self.strActionInfo.setLabel('Guide')

    def drawChannelsPrograms(self):
        #Draw Channels List
        self.lstChannels = SageLib.clist(2,94,164,260)
        self.addControl(self.lstChannels)
        #Draw Listings List
        self.lstPrograms = SageLib.clist(178,94,450,260)
        self.addControl(self.lstPrograms)
        self.lstChannels.controlRight(self.lstPrograms)
        self.lstPrograms.controlLeft(self.lstChannels)
        #Draw Description Text
        self.lblTitle = SageLib.flabel(178,360,450,20)
        self.lblDescription = SageLib.flabel(178,380,450,20)
        self.lblChannelTime = SageLib.flabel(178,400,450,20)
        self.addControl(self.lblTitle)
        self.addControl(self.lblDescription)
        self.addControl(self.lblChannelTime)

    def drawIcons(self):
        #Draw Watched and Archived images
        self.imgWatched = SageLib.image(178,420,20,20,settings.imgWatchedS)
        self.addControl(self.imgWatched)
        self.imgArchived = SageLib.image(201,420,20,20,settings.imgLock)
        self.addControl(self.imgArchived)
        self.imgDontLike = SageLib.image(224,420,20,20,settings.imgDontLikeS)
        self.addControl(self.imgDontLike)
        self.imgWatched.setVisible(False)
        self.imgArchived.setVisible(False)
        self.imgDontLike.setVisible(False)

    def fillChannels(self):
        WebXML = SageLib.GetWebPage(webaddress + "/sagex/rpcXbmc/ChannelAPI/GetAllChannels")
        xmldoc = SageLib.WebXMLContent(WebXML)
        self.channels = SageLib.ParseIt().channels(xmldoc)
        xmldoc.unlink()
        #Fill Channels
        self.lstChannels.reset()
        if not Emulating:
            for i in range(len(self.channels)):
                self.lstChannels.addItem(xbmcgui.ListItem(label=(self.channels[i].channelNumber+" - "+self.channels[i].channelName)))

    def fillPrograms(self, index):
        # Times must be in milliseconds
        startTime = int(time.mktime(datetime.datetime.now().timetuple()))*1000
        endTime   = startTime + (14*24*60*60*1000) # 14 days in advance
        channelId = self.channels[index].channelId
        xmldoc    = SageLib.GetAsXML(webaddress + "/sagex/rpcXbmc/Database/GetAiringsOnChannelAtTime/channel:"+channelId+"/"+str(startTime)+"/"+str(endTime)+"/false/sortby:date")
        self.ChannelPrograms = SageLib.ParseIt().showsLtd(xmldoc)
        xmldoc.unlink()
        #Fill Programs
        self.lstPrograms.reset()
        if not Emulating:
            for i in range(len(self.ChannelPrograms)):
                listitem = xbmcgui.ListItem()
                if (self.ChannelPrograms[i].episode != "" and ShowEpisodeNames):
                    listitem.setLabel(str(i+1) + '. ' + self.ChannelPrograms[i].title + ' - "' + self.ChannelPrograms[i].episode + '"')
                else:
                    listitem.setLabel(str(i+1) + '. ' + self.ChannelPrograms[i].title)
                listitem.setLabel2(self.ChannelPrograms[i].datestamp)
                self.lstPrograms.addItem(listitem)

    def onAction(self, value):
        action = value.getId()
        if (action == ACTION_MENU or action == ACTION_BACK): self.close()
        elif (action == ACTION_MOVE_LEFT or action == ACTION_MOVE_RIGHT
            or action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN
            or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN
            or action == ACTION_SCROLL_UP or action == ACTION_SCROLL_DOWN):

            def SubthreadUpdate(self):
                if action == ACTION_MOVE_LEFT:
                    self.setFocus(self.lstChannels)
                elif action == ACTION_MOVE_RIGHT:
                    self.setFocus(self.lstPrograms)
                self.lblTitle.reset()
                self.lblDescription.reset()
                self.lblChannelTime.reset()
                if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].episode != "":
                    self.lblDescription.addLabel('"' + self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].episode + '" ' + self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].description)
                else:
                    self.lblDescription.addLabel(self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].description)
                self.lblTitle.addLabel(self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].title)
                self.lblChannelTime.addLabel(self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].channel + " " + self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].datestamp)
                if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].AiringArchived: self.imgArchived.setVisible(True)
                else: self.imgArchived.setVisible(False)
                if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].AiringWatched: self.imgWatched.setVisible(True)
                else: self.imgWatched.setVisible(False)
                if self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].dontlike: self.imgDontLike.setVisible(True)
                else: self.imgDontLike.setVisible(False)

            subThread = threading.Thread(target=SubthreadUpdate, args=[self])
            subThread.setDaemon(True)
            xbmcgui.lock()
            subThread.start()
            subThread.join(0.05)
            xbmcgui.unlock()


    def onControl(self, control):
        global SelectedProgram
        if control == self.lstChannels:
            self.fillPrograms(self.lstChannels.getSelectedPosition())
        elif control == self.lstPrograms:
            SelectedProgram = SageLib.Program(0, self.ChannelPrograms[self.lstPrograms.getSelectedPosition()].AiringSageDbId)
            popup = SageProgramInfo()
            popup .doModal()
            del popup

if Connect:
    mydisplay = SageMain()
    mydisplay .doModal()
    del mydisplay
